package sg.techstudio.suntec.controller;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import sg.techstudio.suntec.dao.EventContactDao;
import sg.techstudio.suntec.dao.RadiusDao;
import sg.techstudio.suntec.object.BookObj;
import sg.techstudio.suntec.object.Radcheck;
import sg.techstudio.suntec.object.RestEventContactObj;
import sg.techstudio.suntec.object.WifiAccountObj;
import sg.techstudio.suntec.validator.RestValidator;

@Controller
public class RestController extends BaseController {

	private static final Log log = LogFactory.getLog(RestController.class);
	
	@Autowired
	private EventContactDao eventContactDao;
	
	@Autowired
	private RadiusDao radiusDao;
	
	@Autowired
	private RestValidator restValidator;
	
	@Override
	protected String getModuleFolder() {
		return "rest/";
	}

	@ResponseBody
	@RequestMapping(value="rest1"+SPRING_EXT)
	public BookObj rest1(Model model) {
		log.debug("rest1() entry");
		BookObj b = new BookObj();
		b.setId(2);
		b.setName("bookname");
		b.setStartDate(Calendar.getInstance().getTime());
		return b;
	}
	
	@ResponseBody
	@RequestMapping(value="rest2"+SPRING_EXT, headers="Accept=application/json")
	public BookObj rest2(@RequestBody BookObj b) {
		log.debug("rest2() entry");
		log.debug("received book: "+b.getId()+":"+b.getName());
//		b = new BookObj();
//		b.setId(2);
		b.setName(b.getName()+" adding text");
		
//		return new ModelAndView(jsonView, "bookObj", b);
		return b;
	}
	
	@ResponseBody
	@RequestMapping(value="rest3"+SPRING_EXT)
	public RestEventContactObj rest3(Model model) {
		log.debug("rest3() entry");
		RestEventContactObj r = new RestEventContactObj();
		List<WifiAccountObj> l = new ArrayList<WifiAccountObj>();
		WifiAccountObj w = new WifiAccountObj();
		w.setMaxDevices(2);
		w.setPackageType(1);
		w.setWifiUsername("u");
		w.setWifiPassword("p");
		l.add(w);
		w = new WifiAccountObj();
		w.setMaxDevices(3);
		w.setPackageType(2);
		w.setWifiUsername("22");
		w.setWifiPassword("1132p");
		l.add(w);
		r.setWifiAccoutList(l);
		r.setActivateEndDate(Calendar.getInstance().getTime());
		r.setActivateStartDate(Calendar.getInstance().getTime());
		r.setActive(true);
		r.setContactEmail("email@e.com");
		r.setExtId(2L);
		return r;
	}

	/*block this for airshow
	 * @ResponseBody
	@RequestMapping(value="addmodify"+SPRING_EXT, headers="Accept=application/json")
	@PreAuthorize("hasRole('ROLE_REST')")
	public RestResponseObj addModify(@RequestBody RestEventContactObj ec) {
		log.debug("addModify() entry");
		
		RestResponseObj ret = restValidator.validate(ec);
		if(ret!=null) {
			return ret;
		}
		
		RestEventContactObj ec2 = eventContactDao.findEventContact(ec);
		if(ec2!=null) {
			ec.setId(ec2.getId());
			ec.setCreatedDate(ec2.getCreatedDate());
			ec.setUpdatedDate(ec2.getUpdatedDate());
		}
		
		Set<WifiAccountObj> addSet = new HashSet<WifiAccountObj>()
				, deleteSet = new HashSet<WifiAccountObj>()
				, modifySet = new HashSet<WifiAccountObj>();
		if(ec2!=null && ec2.getWifiAccoutList()!=null) //run through existing list
			for(WifiAccountObj w: ec2.getWifiAccoutList()) {
				WifiAccountObj wnew = findInCollection(w.getWifiUsername(), ec.getWifiAccoutList());
				if(wnew==null) { //delete case
					deleteSet.add(w);
				} else { //modify
					wnew.setId(w.getId());
					modifySet.add(w);
				}
			}
		if(ec.getWifiAccoutList()!=null)
			for(WifiAccountObj w: ec.getWifiAccoutList()) {
				if(w.getId()==null) //add case
					addSet.add(w);
			}
		
		eventContactDao.saveEventContact(ec);
		eventContactDao.deleteWifiAccount(deleteSet);

		radiusDao.deleteRadcheckByUsername(convertWifiAccountUsernames(deleteSet));
		radiusDao.saveRadcheck(convertWifiAccountCol(addSet));
		radiusDao.updateRadcheck(convertWifiAccountColWithId(modifySet));
		
		RestResponseObj resp = new RestResponseObj();
		resp.setMessage("success");
		return resp;
	}
	*/
	protected WifiAccountObj findInCollection(String username, Collection<WifiAccountObj> acctCol) {
		if(acctCol==null)
			return null;
		for(WifiAccountObj w: acctCol)
			if(StringUtils.equalsIgnoreCase(username, w.getWifiUsername()))
				return w;
		return null;
	}
	
	protected Collection<Radcheck> convertWifiAccountColWithId(Collection<WifiAccountObj> wifiCol){
		Collection<Radcheck> ret = radiusDao.getRadCheckByName(convertWifiAccountUsernames(wifiCol));
		if(ret==null)
			return null;
		for(Radcheck r: ret) {
			WifiAccountObj w = findInCollection(r.getUsername(), wifiCol);
			if(w==null)
				continue;
			r.setValue(DigestUtils.md5Hex(w.getWifiPassword()));
		}
		return ret;
	}
	
	protected Collection<String> convertWifiAccountUsernames(Collection<WifiAccountObj> wifiCol){
		if(wifiCol==null)
			return null;
		Collection<String> ret = new HashSet<String>();
		for(WifiAccountObj w: wifiCol)
			ret.add(w.getWifiUsername());
		return ret;
	}
	
	protected Collection<Radcheck> convertWifiAccountCol(Collection<WifiAccountObj> wifiCol){
		if(wifiCol==null)
			return null;
		Collection<Radcheck> ret = new HashSet<Radcheck>();
		for(WifiAccountObj w: wifiCol)
			ret.add(buildRadcheck(w.getWifiUsername(), w.getWifiPassword()));
		return ret;
	}
	
	protected Radcheck buildRadcheck(String username, String password) {
		Radcheck r = new Radcheck();
		r.setAttribute("MD5-Password");
		r.setUsername(username);
		r.setOp(":=");
		r.setValue(DigestUtils.md5Hex(password));
		return r;
	}
	
}
